package com.yorick.authority.service.impl;

import com.yorick.authority.entitys.*;
import com.yorick.authority.modal.request.account.*;
import com.yorick.authority.modal.response.account.AccountEditResponse;
import com.yorick.authority.modal.response.BaseListResponse;
import com.yorick.authority.service.AbstractAuthorityService;
import com.yorick.authority.service.AccountService;
import com.yorick.common.Result.SimpleFactory.ResultFactory;
import com.yorick.common.error.YorickAssert;
import com.yorick.common.util.Encrypt;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class AccountServiceImpl extends AbstractAuthorityService implements AccountService {

    @Override
    public Map<String, Object> addAccount(AccountAddRequest request) {
        AccountDto accountDto = AccountDto.builder()
                .account(request.getAccount())
                .mobilephone(request.getMobilephone())
                .username(request.getUsername())
                .build();
        List<AccountDto> isExist = accountsMapper.isAccountExist(accountDto);
        YorickAssert.validate(
                isExist.size() == 0,
                () -> "0",
                () -> "账户已存在");
        //添加用户信息
        String password = Encrypt.encrypt(request.getAccount() + request.getPassword());
        accountDto.setPassword(password);
        accountsMapper.insertAccount(accountDto);
        //添加用户角色
        insertUserRole(request.getRoleList(), accountDto.getAid());
        //添加用户部门
        insertUserDepartment(request.getDepartmentList(), accountDto.getAid());
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    public BaseListResponse accountList(AccountListRequest request) {
        Integer currentPage = request.getCurrentPage();
        Integer pageSize = request.getPageSize();
        Integer start = (currentPage - 1) * pageSize;
        BaseListDto data = BaseListDto.builder()
                .start(start)
                .pageSize(pageSize)
                .superRole(request.isSuperRole())
                .keyword(request.getKeyword())
                .dids(getDID(request.getAid()))
                .build();

        List<AccountDto> list = accountsMapper.findAccountList(data);
        list.parallelStream().forEach(
                account -> {
                    account.setDepartment(getDName(account.getAid()));
                }
        );
        BaseListResponse response = BaseListResponse.builder()
                .list(list)
                .total(accountsMapper.findAccountTotal(data))
                .build();
        return response;
    }

    @Override
    public Map<String, Object> editAccount(AccountEditRequest request) {
        String mobilePhone = accountsMapper.isPhoneExist(request.getMobilephone());
        YorickAssert.validate(
                Objects.isNull(mobilePhone) ||
                        mobilePhone.equals(request.getAccount()),
                () -> "0",
                () -> "手机号已存在"
        );
        AccountDto accountDto = AccountDto.builder()
                .username(request.getUsername())
                .account(request.getAccount())
                .mobilephone(request.getMobilephone())
                .enabled(request.getEnabled())
                .aid(request.getAid())
                .build();

        if (StringUtils.isNoneBlank(request.getPassword())) {
            String password = Encrypt.encrypt(request.getAccount() + request.getPassword());
            accountDto.setPassword(password);
        }
        //更新用户基本信息
        accountsMapper.updateAccount(accountDto);

        //首先删除原有的机构和角色
        accountsMapper.deleteUserDepartByAID(request.getAid());
        accountsMapper.deleteUserRoleByAID(request.getAid());

        //添加用户角色
        insertUserRole(request.getRoleList(), request.getAid());
        //添加用户部门
        insertUserDepartment(request.getDepartmentList(), request.getAid());
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    public AccountEditResponse accountDetail(AccountDetailRequest request) {
        AccountDto accountDto = accountsMapper.findAccountByAID(request.getAid());
        AccountEditResponse response = AccountEditResponse.builder()
                .aid(accountDto.getAid())
                .account(accountDto.getAccount())
                .username(accountDto.getUsername())
                .mobilephone(accountDto.getMobilephone())
                .email(accountDto.getEmail())
                .login_date(accountDto.getLoginDate())
                .enabled(accountDto.getEnabled())
                .roleList(accountsMapper.getRolesByAID(request.getAid()))
                .departmentList(accountsMapper.getDepartByAID(request.getAid()))
                .build();
        return response;
    }

    @Override
    public Map<String, Object> editPassword(AccountChangePasswordRequest request) {
        String oldPassword = Encrypt.encrypt(request.getAccount() +
                request.getOldPassword());

        AccountDto accountDto = AccountDto.builder()
                .aid(request.getAid())
                .password(oldPassword)
                .build();

        Integer isPasswordCorrect = accountsMapper.isPasswordCorrect(accountDto);
        YorickAssert.validate(
                isPasswordCorrect > 0,
                () -> "0",
                () -> "原密码错误"
        );

        String password = Encrypt.encrypt(request.getAccount() +
                request.getPassword());
        accountDto.setPassword(password);
        accountsMapper.updatePasswordByAID(accountDto);
        return ResultFactory.success().display();

    }

    @Override
    public Map<String, Object> editAccountStatus(AccountChangeStatusRequest request) {
        AccountDto accountDto = AccountDto.builder()
                .aid(request.getAid())
                .enabled(request.getEnabled())
                .build();
        accountsMapper.updateAccountStatus(accountDto);
        return ResultFactory.success().display();
    }

}
